<template>
  <PageCard title="二维码生成器">
    <div class="qrcode-generator-container">
      <!-- 主要内容区域 -->
      <div class="main-content">
        <n-grid :cols="isMobile ? 1 : 2" :x-gap="32" :y-gap="24">
          <!-- 左侧输入区 -->
          <n-gi>
            <n-card title="输入内容" :bordered="false" class="input-card">
              <n-form>
                <n-form-item :show-label="false">
                  <n-input
                    v-model:value="inputContent"
                    type="textarea"
                    :rows="10"
                    placeholder="请输入文本或链接，如：https://example.com 或任意文本内容"
                    :maxlength="2000"
                    show-count
                  />
                </n-form-item>

                  <div class="action-buttons">
                    <n-grid :cols="12" :x-gap="12" :y-gap="12">
                      <n-gi :span="isMobile ? 3 : 2">
                        <n-button size="large" tertiary block @click="showSettings = true">
                          <template #icon>
                            <n-icon>
                              <SettingsOutline />
                            </n-icon>
                          </template>
                        </n-button>
                      </n-gi>

                      <n-gi :span="isMobile ? 9 : 5">
                        <n-button
                          type="primary"
                          size="large"
                          block
                          @click="generateQRCode"
                          :loading="generating"
                          :disabled="!inputContent.trim()"
                        >
                          <template #icon>
                            <n-icon>
                              <svg viewBox="0 0 24 24">
                                <path fill="currentColor" d="M3 11h8V3H3v8zm2-6h4v4H5V5zm8-2v8h8V3h-8zm6 6h-4V5h4v4zM3 21h8v-8H3v8zm2-6h4v4H5v-4zm13 6h1v-3h2v-2h-2v-2h2v-2h-2v-3h-2v3h-3v2h3v2h-3v2h3v3zm0-8v2h-2v-2h2z"/>
                              </svg>
                            </n-icon>
                          </template>
                          生成二维码
                        </n-button>
                      </n-gi>

                      <n-gi :span="isMobile ? 12 : 5">
                        <n-button
                          type="warning"
                          size="large"
                          block
                          @click="clearContent"
                          :disabled="generating"
                        >
                          <template #icon>
                            <n-icon>
                              <svg viewBox="0 0 24 24">
                                <path fill="currentColor" d="M19 6.41L17.59 5L12 10.59L6.41 5L5 6.41L10.59 12L5 17.59L6.41 19L12 13.41L17.59 19L19 17.59L13.41 12z"/>
                              </svg>
                            </n-icon>
                          </template>
                          清空内容
                        </n-button>
                      </n-gi>
                    </n-grid>
                  </div>
                </n-form>
            </n-card>
          </n-gi>

          <!-- 右侧展示区 -->
          <n-gi>
            <n-card title="生成结果" :bordered="false" class="result-card">
              <n-spin :show="generating">
                <template #description>
                  正在生成二维码，请稍候...
                </template>
                <div class="qrcode-display">
                  <div v-if="qrcodeImage" class="qrcode-wrapper">
                    <div class="qrcode-container">
                      <img :src="qrcodeImage" alt="QR Code" class="qrcode-image" />
                    </div>

                    <div class="qrcode-actions">
                      <n-button @click="showLogoModal = true" tertiary>
                        <template #icon>
                          <n-icon>
                            <CloudUploadOutline />
                          </n-icon>
                        </template>
                        添加Logo
                      </n-button>

                      <n-button @click="downloadQRCode" type="primary">
                        <template #icon>
                          <n-icon>
                            <svg viewBox="0 0 24 24">
                              <path fill="currentColor" d="M19 12v7H5v-7H3v7c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2v-7h-2zm-6 .67l2.59-2.58L17 11.5l-5 5-5-5 1.41-1.41L11 12.67V3h2v9.67z"/>
                            </svg>
                          </n-icon>
                        </template>
                        下载图片
                      </n-button>
                    </div>
                  </div>
                  <div v-else class="empty-state">
                    <n-icon size="80" color="#c0c0c0">
                      <svg viewBox="0 0 24 24">
                        <path fill="currentColor" d="M3 11h8V3H3v8zm2-6h4v4H5V5zm8-2v8h8V3h-8zm6 6h-4V5h4v4zM3 21h8v-8H3v8zm2-6h4v4H5v-4zm13 6h1v-3h2v-2h-2v-2h2v-2h-2v-3h-2v3h-3v2h3v2h-3v2h3v3zm0-8v2h-2v-2h2z"/>
                      </svg>
                    </n-icon>
                    <p>二维码将在这里显示</p>
                  </div>
                </div>
              </n-spin>
            </n-card>
          </n-gi>
        </n-grid>
      </div>

      <n-divider />

      <!-- 生成历史 -->
      <div class="history-section">
        <div class="history-header">
          <h3>生成历史</h3>
          <n-button
            v-if="historyList.length > 0"
            text
            @click="clearHistory"
          >
            清空历史
          </n-button>
        </div>

        <div v-if="historyList.length > 0" class="history-list">
          <n-grid :cols="1" :y-gap="12">
            <n-gi v-for="item in historyList" :key="item.id">
              <div class="history-item" @click="viewHistoryItem(item)">
                <div class="history-content">
                  <span class="history-text">{{ truncateText(item.content) }}</span>
                  <span class="history-time">{{ formatTime(item.timestamp) }}</span>
                </div>
                <n-button text type="primary">
                  查看
                </n-button>
              </div>
            </n-gi>
          </n-grid>
        </div>
        <div v-else class="empty-history">
          <p>暂无历史记录</p>
        </div>
      </div>
    </div>

    <n-divider />

    <UsageGuide
      :title="usageGuideConfig.title"
      :steps="usageGuideConfig.steps"
      :tips="usageGuideConfig.tips"
      :example="usageGuideConfig.example"
    />

    <!-- Logo配置弹窗 -->
    <n-modal
      v-model:show="showLogoModal"
      preset="card"
      title="添加Logo到二维码"
      style="width: 600px; max-width: 90vw;"
      :mask-closable="false"
    >
      <n-form>
        <n-form-item label="上传Logo图片" :show-feedback="false">
          <div v-if="!logoUrl" class="logo-upload-area">
            <n-upload
              :action="uploadApi"
              :max="1"
              accept="image/*"
              :show-file-list="false"
              @finish="handleLocalLogoFinish"
              @before-upload="beforeLogoUpload"
              :default-upload="false"
            >
              <n-upload-dragger style="width: 100%; min-height: 200px;">
                <div style="margin-bottom: 12px">
                  <n-icon size="40" :depth="3">
                    <CloudUploadOutline />
                  </n-icon>
                </div>
                <n-text style="font-size: 14px;">
                  点击或拖拽上传Logo图片
                </n-text>
                <n-p depth="3" style="margin: 8px 0; font-size: 12px;">
                  支持 JPG / PNG 格式，建议使用透明背景的PNG图片
                </n-p>
              </n-upload-dragger>
            </n-upload>
          </div>
          <div v-else class="logo-preview-area">
            <n-image
              :src="logoUrl"
              width="150"
              height="150"
              object-fit="contain"
              style="border: 1px solid #e0e0e0; border-radius: 8px; padding: 10px; background: #f5f5f5;"
            />
            <n-button
              class="logo-remove-button"
              type="error"
              size="small"
              circle
              @click="logoUrl = ''"
            >
              <template #icon>
                <n-icon>
                  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
                    <path fill="currentColor" d="M19 6.41L17.59 5L12 10.59L6.41 5L5 6.41L10.59 12L5 17.59L6.41 19L12 13.41L17.59 19L19 17.59L13.41 12L19 6.41z"/>
                  </svg>
                </n-icon>
              </template>
            </n-button>
          </div>
        </n-form-item>

        <n-grid :cols="2" :x-gap="16">
          <n-gi>
            <n-form-item label="Logo宽度">
              <n-input-number
                v-model:value="logoWidth"
                :min="20"
                :max="150"
                :step="10"
                style="width: 100%;"
              >
                <template #suffix>px</template>
              </n-input-number>
            </n-form-item>
          </n-gi>
          <n-gi>
            <n-form-item label="Logo高度">
              <n-input-number
                v-model:value="logoHeight"
                :min="20"
                :max="150"
                :step="10"
                style="width: 100%;"
              >
                <template #suffix>px</template>
              </n-input-number>
            </n-form-item>
          </n-gi>
        </n-grid>

        <n-form-item label="去除白边">
          <n-switch v-model:value="removeWhiteBorder" />
        </n-form-item>
      </n-form>

      <template #footer>
        <n-space justify="end">
          <n-button @click="showLogoModal = false">
            取消
          </n-button>
          <n-button
            type="primary"
            @click="generateQRCodeWithLogo"
            :loading="generatingWithLogo"
            :disabled="!logoUrl"
          >
            生成带Logo的二维码
          </n-button>
        </n-space>
      </template>
    </n-modal>

    <!-- 二维码设置弹窗 -->
    <n-modal
      v-model:show="showSettings"
      preset="card"
      title="二维码设置"
      style="width: 500px; max-width: 90vw;"
      :mask-closable="true"
    >
      <n-form>
        <n-form-item label="尺寸">
          <n-radio-group v-model:value="sizeOption" @update:value="handleSizeChange">
            <n-grid :cols="2" :x-gap="12" :y-gap="12">
              <n-gi>
                <n-radio value="300">300x300px</n-radio>
              </n-gi>
              <n-gi>
                <n-radio value="400">400x400px</n-radio>
              </n-gi>
              <n-gi>
                <n-radio value="500">500x500px</n-radio>
              </n-gi>
              <n-gi>
                <n-radio value="600">600x600px</n-radio>
              </n-gi>
              <n-gi :span="2">
                <div style="display: flex; align-items: center; gap: 8px;">
                  <n-radio value="custom">自定义尺寸</n-radio>
                  <n-input-number
                    v-if="sizeOption === 'custom'"
                    v-model:value="qrcodeSize"
                    :min="100"
                    :max="800"
                    :step="50"
                    placeholder="尺寸"
                    style="flex: 1;"
                  >
                    <template #suffix>px</template>
                  </n-input-number>
                </div>
              </n-gi>
            </n-grid>
          </n-radio-group>
        </n-form-item>
        
        <n-form-item label="边距">
          <n-input-number
            v-model:value="qrcodeMargin"
            :min="0"
            :max="20"
            :step="1"
            style="width: 100%;"
          >
            <template #suffix>px</template>
          </n-input-number>
        </n-form-item>
      </n-form>

      <template #footer>
        <n-space justify="end">
          <n-button @click="showSettings = false">
            关闭
          </n-button>
          <n-button
            type="primary"
            @click="handleSettingsConfirm"
          >
            确定
          </n-button>
        </n-space>
      </template>
    </n-modal>
  </PageCard>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue'
import {
  NInput,
  NButton,
  NIcon,
  NDivider,
  NSpin,
  NForm,
  NFormItem,
  NGrid,
  NGridItem as NGi,
  NSpace,
  NUpload,
  NUploadDragger,
  NCard,
  NModal,
  NInputNumber,
  NSwitch,
  NRadio,
  NRadioGroup,
  NImage,
  NText,
  NP,
  useMessage,
  useDialog,
  type UploadFileInfo
} from 'naive-ui'
import PageCard from '@/components/PageCard.vue'
import UsageGuide from '@/components/UsageGuide.vue'
import { useBreakpoint } from '@/utils/responsive-helper'
import { QRCodeApi } from '@/api/utility/qrcode'
import { QRCodeHistoryDB } from '@/utils/qrcode-history'
import { SettingsOutline, CloudUploadOutline } from '@vicons/ionicons5'
import { uploadApi } from '@/api/oss'

const message = useMessage()
const dialog = useDialog()
const { isMobile } = useBreakpoint()

// 数据定义
const inputContent = ref('')
const qrcodeImage = ref('')
const generating = ref(false)
const uploadingLogo = ref(false)
const logoFileList = ref<UploadFileInfo[]>([])
const historyList = ref<any[]>([])

// 设置相关
const showSettings = ref(false)
const sizeOption = ref('300')
const qrcodeSize = ref(300)
const qrcodeMargin = ref(2)

// Logo配置弹窗
const showLogoModal = ref(false)
const logoUrl = ref('')
const logoWidth = ref(60)
const logoHeight = ref(60)
const removeWhiteBorder = ref(true)
const generatingWithLogo = ref(false)
const uploadingLocalLogo = ref(false)

// 历史记录数据库
const historyDB = new QRCodeHistoryDB()

// 使用说明配置
const usageGuideConfig = {
  title: '使用说明',
  steps: [
    '在输入框中输入文本或链接',
    '点击"生成二维码"按钮',
    '等待二维码生成完成',
    '（可选）上传Logo图片添加到二维码中心',
    '点击"下载图片"保存二维码'
  ],
  tips: [
    '支持输入任意文本、链接、WiFi信息等内容',
    '上传的Logo会自动缩放并居中显示',
    '生成的二维码支持扫码识别',
    '历史记录保存在本地浏览器中'
  ],
  example: '输入网址如 https://github.com 生成对应的二维码，可添加公司Logo使其更具品牌特色'
}

// 处理尺寸选项变化
const handleSizeChange = (value: string) => {
  if (value !== 'custom') {
    qrcodeSize.value = parseInt(value)
  }
}

// 处理设置确认
const handleSettingsConfirm = () => {
  showSettings.value = false
  message.success('设置已保存')
}

// 生成二维码
const generateQRCode = async () => {
  if (!inputContent.value.trim()) {
    message.warning('请输入内容')
    return
  }

  generating.value = true
  try {
    const res = await QRCodeApi.generateQRCode({
      content: inputContent.value.trim(),
      size: qrcodeSize.value,
      margin: qrcodeMargin.value
    })

    if (res.code === 200 && res.data) {
      qrcodeImage.value = res.data

      // 保存到历史记录
      await historyDB.addHistory({
        content: inputContent.value.trim(),
        qrcodeImage: res.data,
        timestamp: Date.now(),
        hasLogo: false
      })

      // 刷新历史记录列表
      await loadHistory()

      message.success('二维码生成成功')
    } else {
      message.error(res.message || '生成失败')
    }
  } catch (error: any) {
    message.error(error.message || '生成失败，请稍后重试')
  } finally {
    generating.value = false
  }
}

// 生成带Logo的二维码（云端）
const generateQRCodeWithLogo = async () => {
  if (!inputContent.value.trim()) {
    message.warning('请先输入二维码内容')
    return
  }

  if (!logoUrl.value) {
    message.warning('请上传Logo图片')
    return
  }

  generatingWithLogo.value = true
  try {
    const res = await QRCodeApi.generateCloudQRCode({
      content: inputContent.value.trim(),
      size: qrcodeSize.value,
      margin: qrcodeMargin.value,
      logoUrl: logoUrl.value.trim(),
      logoWidth: logoWidth.value,
      logoHeight: logoHeight.value,
      removeWhiteBorder: removeWhiteBorder.value
    })

    if (res.code === 200 && res.data) {
      qrcodeImage.value = res.data

      // 保存到历史记录
      await historyDB.addHistory({
        content: inputContent.value.trim(),
        qrcodeImage: res.data,
        timestamp: Date.now(),
        hasLogo: true
      })

      // 刷新历史记录列表
      await loadHistory()

      message.success('带Logo的二维码生成成功')
      showLogoModal.value = false
      logoUrl.value = ''
    } else {
      message.error(res.message || '生成失败')
    }
  } catch (error: any) {
    message.error(error.message || '生成失败，请稍后重试')
  } finally {
    generatingWithLogo.value = false
  }
}

// Logo上传前的验证
const beforeLogoUpload = (data: {
  file: UploadFileInfo
  fileList: UploadFileInfo[]
}) => {
  const file = data.file.file
  if (!file) return false

  const isImage = file.type.startsWith('image/')
  if (!isImage) {
    message.error('请上传图片文件')
    return false
  }

  const isLt2M = file.size / 1024 / 1024 < 2
  if (!isLt2M) {
    message.error('Logo图片大小不能超过2MB')
    return false
  }

  // 手动处理上传
  handleLogoUploadAction(data)
  return false
}

// 处理Logo上传动作
const handleLogoUploadAction = async (data: {
  file: UploadFileInfo
  fileList: UploadFileInfo[]
}) => {
  const file = data.file.file
  if (!file) return

  const formData = new FormData()
  formData.append('file', file)

  uploadingLocalLogo.value = true

  try {
    const response = await fetch(uploadApi as string, {
      method: 'POST',
      body: formData
    })

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`)
    }

    const result = await response.json()

    if (result.code === 200) {
      logoUrl.value = result.data
      message.success('Logo上传成功')
    } else {
      message.error(result.message || '上传失败')
    }
  } catch (error) {
    console.error('Upload error:', error)
    message.error('上传失败：请确保后端服务已启动')
  } finally {
    uploadingLocalLogo.value = false
  }
}

// 处理上传完成
const handleLocalLogoFinish = ({
  file,
  event
}: {
  file: UploadFileInfo
  event?: ProgressEvent
}) => {
  try {
    const response = (event?.currentTarget as XMLHttpRequest)?.response
    if (response) {
      const parse = JSON.parse(response)
      if (parse.code === 200) {
        file.url = parse.data
        logoUrl.value = parse.data
        message.success('Logo上传成功')
      } else {
        message.error(parse.message || '上传失败')
      }
    } else {
      message.error('上传失败：服务器无响应')
    }
  } catch (error) {
    console.error('Upload error:', error)
    message.error('上传失败：请确保后端服务已启动')
  }
  return file
}

// 下载二维码
const downloadQRCode = () => {
  if (!qrcodeImage.value) {
    message.warning('请先生成二维码')
    return
  }

  const link = document.createElement('a')
  link.href = qrcodeImage.value
  link.download = `qrcode-${Date.now()}.png`
  link.click()
  message.success('下载成功')
}

// 清空输入
const clearContent = () => {
  inputContent.value = ''
  qrcodeImage.value = ''
  logoFileList.value = []
}

// 加载历史记录
const loadHistory = async () => {
  try {
    historyList.value = await historyDB.getHistory()
  } catch (error) {
    console.error('加载历史记录失败:', error)
  }
}

// 查看历史记录项
const viewHistoryItem = (item: any) => {
  inputContent.value = item.content
  qrcodeImage.value = item.qrcodeImage
}

// 清空历史记录
const clearHistory = () => {
  dialog.warning({
    title: '确认清空',
    content: '确定要清空所有历史记录吗？此操作不可恢复。',
    positiveText: '确定',
    negativeText: '取消',
    onPositiveClick: async () => {
      try {
        await historyDB.clearHistory()
        historyList.value = []
        message.success('历史记录已清空')
      } catch (error) {
        message.error('清空失败')
      }
    }
  })
}

// 截断文本
const truncateText = (text: string, maxLength: number = 50) => {
  return text.length > maxLength ? text.substring(0, maxLength) + '...' : text
}

// 格式化时间
const formatTime = (timestamp: number) => {
  const date = new Date(timestamp)
  const now = new Date()
  const diff = now.getTime() - date.getTime()
  const days = Math.floor(diff / (1000 * 60 * 60 * 24))

  if (days === 0) {
    const hours = date.getHours().toString().padStart(2, '0')
    const minutes = date.getMinutes().toString().padStart(2, '0')
    return `今天 ${hours}:${minutes}`
  } else if (days === 1) {
    return '昨天'
  } else if (days < 7) {
    return `${days}天前`
  } else {
    const month = (date.getMonth() + 1).toString().padStart(2, '0')
    const day = date.getDate().toString().padStart(2, '0')
    return `${month}-${day}`
  }
}

// 生命周期
onMounted(() => {
  loadHistory()
})
</script>

<style scoped lang="less">
.qrcode-generator-container {
  max-width: 1200px;
  margin: 0 auto;
}

.main-content {
  margin-bottom: 32px;
}

.input-card,
.result-card {
  height: 100%;
  min-height: 500px;

  :deep(.n-card__content) {
    height: calc(100% - 56px);
    display: flex;
    flex-direction: column;
  }
}

.logo-upload-area {
  width: 100%;
}

.logo-preview-area {
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 20px;
  background: #fafafa;
  border-radius: 8px;

  @media (prefers-color-scheme: dark) {
    background: rgba(255, 255, 255, 0.05);
  }

  .logo-remove-button {
    position: absolute;
    top: 10px;
    right: 10px;
    z-index: 10;
  }
}

.action-buttons {
  margin-top: 16px;
}

.qrcode-display {
  height: 100%;
  min-height: 320px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.qrcode-wrapper {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 24px;
}

.qrcode-container {
  padding: 20px;
  background: white;
  border-radius: 12px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);

  @media (prefers-color-scheme: dark) {
    background: rgba(255, 255, 255, 0.08);
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);
  }
}

.qrcode-image {
  display: block;
  width: 280px;
  height: 280px;
  image-rendering: pixelated;
}

.qrcode-actions {
  display: flex;
  gap: 12px;

  @media (max-width: 768px) {
    flex-direction: column;
    width: 100%;

    .n-button {
      width: 100%;
    }
  }
}

.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 280px;

  p {
    margin-top: 16px;
    font-size: 14px;
    color: #999;
  }
}

.history-section {
  margin-top: 24px;
}

.history-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;

  h3 {
    margin: 0;
    font-size: 18px;
    font-weight: 500;
    color: #333;

    @media (prefers-color-scheme: dark) {
      color: #e0e0e0;
    }
  }
}

.history-list {
  background: #f5f5f5;
  border-radius: 8px;
  padding: 16px;
  max-height: 300px;
  overflow-y: auto;

  @media (prefers-color-scheme: dark) {
    background: rgba(255, 255, 255, 0.05);
  }

  &::-webkit-scrollbar {
    width: 8px;
  }

  &::-webkit-scrollbar-track {
    background: rgba(255, 105, 180, 0.1);
    border-radius: 4px;
  }

  &::-webkit-scrollbar-thumb {
    background: rgba(255, 105, 180, 0.3);
    border-radius: 4px;

    &:hover {
      background: rgba(255, 105, 180, 0.5);
    }
  }
}

.history-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px;
  background: white;
  border-radius: 6px;
  cursor: pointer;
  transition: all 0.3s ease;

  &:hover {
    transform: translateX(4px);
    box-shadow: 0 2px 8px rgba(255, 105, 180, 0.15);
  }

  @media (prefers-color-scheme: dark) {
    background: rgba(255, 255, 255, 0.08);
  }
}

.history-content {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}

.history-text {
  font-size: 14px;
  color: #333;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;

  @media (prefers-color-scheme: dark) {
    color: #e0e0e0;
  }
}

.history-time {
  font-size: 12px;
  color: #999;
}

.empty-history {
  text-align: center;
  padding: 40px;
  color: #999;
  font-size: 14px;
}
</style>
